package com.aiwiown.snackmq.broker.auth;

import com.aiwiown.snackmq.cluster.metadata.MetadataManager;
import com.aiwiown.snackmq.common.auth.AuthenticatedUser;
import com.aiwiown.snackmq.common.auth.User;
import com.aiwiown.snackmq.common.handler.MessageHandler;
import com.aiwiown.snackmq.common.handler.RequestContext;
import com.aiwiown.snackmq.common.message.Message;
import com.aiwiown.snackmq.common.message.MessageStatus;
import com.aiwiown.snackmq.common.message.MessageType;
import com.aiwiown.snackmq.common.serialization.JsonSerializer;
import com.aiwiown.snackmq.common.serialization.SerializerFactory;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;

/**
 * 【新增/修复】处理客户端认证请求的处理器。
 * 此实现修复了认证失败时不返回错误消息的问题，并正确生成 JWT。
 */
@Slf4j
@RequiredArgsConstructor
public class AuthenticationHandler implements MessageHandler {

    private final MetadataManager metadataManager;
    private final JwtService jwtService;
    private final JsonSerializer serializer = SerializerFactory.getJsonSerializer();

    @Override
    public MessageType getMessageType() {
        return MessageType.AUTHENTICATE_REQUEST;
    }

    @Override
    public void handle(RequestContext ctx, Message request) {
        String username = request.getProperty("username");
        String password = request.getProperty("password");

        try {
            if (username == null || password == null) {
                sendErrorResponse(ctx, request, "Username and password are required.");
                return;
            }

            User user = metadataManager.getUser(username);

            if (user.getPassword() == null) {
                // 场景二: 用户数据损坏（密码丢失）
                // 这是一个严重问题，需要记录详细的错误日志。
                log.error("CRITICAL: Authentication failed for user '{}'. The stored password for this user is null. " +
                        "This indicates a potential data corruption or a bug in user data handling.", username);
                sendErrorResponse(ctx, request, "User account is corrupted. Please contact administrator.");
                return;
            }

            // 场景三: 密码不匹配或认证成功
            // 在实际系统中，应使用安全的密码哈希机制（如 BCrypt）。
            if (password.equals(user.getPassword())) {
                log.info("Authentication successful for user '{}'. Generating JWT.", username);
                String token = jwtService.generateToken(user.getUsername(), user.getRoles());
                Claims claims = jwtService.validateAndParseToken(token);
                Date expiration = (claims != null) ? claims.getExpiration() : null;

                AuthenticatedUser authUser = new AuthenticatedUser(user.getUsername(), token, user.getRoles(), expiration);

                Message response = Message.builder()
                        .type(MessageType.RESPONSE)
                        .messageId(request.getMessageId())
                        .status(MessageStatus.SUCCESS)
                        .body(serializer.serialize(authUser))
                        .build();
                ctx.writeResponse(response);
            } else {
                log.warn("Authentication failed for user '{}'. Invalid credentials.", username);
                sendErrorResponse(ctx, request, "Invalid username or password.");
            }
        } catch (Exception e) {
            log.error("An error occurred during authentication for user '{}'.", username, e);
            sendErrorResponse(ctx, request, "Internal server error during authentication.");
        }
    }

    private void sendErrorResponse(RequestContext ctx, Message request, String errorMessage) {
        Message response = Message.builder()
                .type(MessageType.RESPONSE)
                .messageId(request.getMessageId())
                .status(MessageStatus.FAILED)
                .errorMessage(errorMessage)
                .build();
        ctx.writeResponse(response);
    }
}